package com.xiaozhi.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaozhi.common.Result;
import com.xiaozhi.entity.Notification;
import com.xiaozhi.service.NotificationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 通知控制器
 * 提供通知系统的REST API接口
 */
@RestController
@RequestMapping("/api/notifications")
@Tag(name = "通知管理", description = "通知系统相关接口")
public class NotificationController {

    private static final Logger log = LoggerFactory.getLogger(NotificationController.class);

    @Autowired
    private NotificationService notificationService;

    /**
     * 创建通知
     */
    @PostMapping
    @Operation(summary = "创建通知", description = "创建新的通知")
    public Result<Notification> createNotification(@RequestBody Notification notification) {
        try {
            Notification result = notificationService.createNotification(notification);
            return Result.success(result);
        } catch (Exception e) {
            log.error("创建通知失败", e);
            return Result.error("创建通知失败: " + e.getMessage());
        }
    }

    /**
     * 创建系统通知
     */
    @PostMapping("/system")
    @Operation(summary = "创建系统通知", description = "创建系统通知")
    public Result<Notification> createSystemNotification(
            @Parameter(description = "用户ID") @RequestParam Long userId,
            @Parameter(description = "标题") @RequestParam String title,
            @Parameter(description = "内容") @RequestParam String content,
            @Parameter(description = "优先级") @RequestParam(name = "priority", defaultValue = "NORMAL") String priority) {
        try {
            Notification result = notificationService.createSystemNotification(userId, title, content, priority);
            return Result.success(result);
        } catch (Exception e) {
            log.error("创建系统通知失败", e);
            return Result.error("创建系统通知失败: " + e.getMessage());
        }
    }

    /**
     * 创建预约通知
     */
    @PostMapping("/appointment")
    @Operation(summary = "创建预约通知", description = "创建预约相关通知")
    public Result<Notification> createAppointmentNotification(
            @Parameter(description = "用户ID") @RequestParam Long userId,
            @Parameter(description = "预约ID") @RequestParam Long appointmentId,
            @Parameter(description = "标题") @RequestParam String title,
            @Parameter(description = "内容") @RequestParam String content,
            @Parameter(description = "计划发送时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime scheduledAt) {
        try {
            Notification result = notificationService.createAppointmentNotification(userId, appointmentId, title, content, scheduledAt);
            return Result.success(result);
        } catch (Exception e) {
            log.error("创建预约通知失败", e);
            return Result.error("创建预约通知失败: " + e.getMessage());
        }
    }

    /**
     * 创建健康提醒通知
     */
    @PostMapping("/health-reminder")
    @Operation(summary = "创建健康提醒", description = "创建健康提醒通知")
    public Result<Notification> createHealthReminderNotification(
            @Parameter(description = "用户ID") @RequestParam Long userId,
            @Parameter(description = "健康记录ID") @RequestParam Long healthRecordId,
            @Parameter(description = "标题") @RequestParam String title,
            @Parameter(description = "内容") @RequestParam String content,
            @Parameter(description = "优先级") @RequestParam(name = "priority", defaultValue = "NORMAL") String priority) {
        try {
            Notification result = notificationService.createHealthReminderNotification(userId, healthRecordId, title, content, priority);
            return Result.success(result);
        } catch (Exception e) {
            log.error("创建健康提醒通知失败", e);
            return Result.error("创建健康提醒通知失败: " + e.getMessage());
        }
    }

    /**
     * 创建分析报告通知
     */
    @PostMapping("/analysis")
    @Operation(summary = "创建分析报告通知", description = "创建分析报告通知")
    public Result<Notification> createAnalysisNotification(
            @Parameter(description = "用户ID") @RequestParam Long userId,
            @Parameter(description = "分析ID") @RequestParam Long analysisId,
            @Parameter(description = "标题") @RequestParam String title,
            @Parameter(description = "内容") @RequestParam String content) {
        try {
            Notification result = notificationService.createAnalysisNotification(userId, analysisId, title, content);
            return Result.success(result);
        } catch (Exception e) {
            log.error("创建分析报告通知失败", e);
            return Result.error("创建分析报告通知失败: " + e.getMessage());
        }
    }

    /**
     * 创建症状评估通知
     */
    @PostMapping("/symptom-assessment")
    @Operation(summary = "创建症状评估通知", description = "创建症状评估通知")
    public Result<Notification> createSymptomAssessmentNotification(
            @Parameter(description = "用户ID") @RequestParam Long userId,
            @Parameter(description = "评估ID") @RequestParam Long assessmentId,
            @Parameter(description = "标题") @RequestParam String title,
            @Parameter(description = "内容") @RequestParam String content,
            @Parameter(description = "优先级") @RequestParam(name = "priority", defaultValue = "NORMAL") String priority) {
        try {
            Notification result = notificationService.createSymptomAssessmentNotification(userId, assessmentId, title, content, priority);
            return Result.success(result);
        } catch (Exception e) {
            log.error("创建症状评估通知失败", e);
            return Result.error("创建症状评估通知失败: " + e.getMessage());
        }
    }

    /**
     * 批量创建通知
     */
    @PostMapping("/batch")
    @Operation(summary = "批量创建通知", description = "批量创建通知")
    public Result<Integer> batchCreateNotifications(
            @Parameter(description = "通知列表") @RequestBody List<Notification> notifications) {
        try {
            Integer count = notificationService.batchCreateNotifications(notifications);
            return Result.success(count);
        } catch (Exception e) {
            log.error("批量创建通知失败", e);
            return Result.error("批量创建通知失败: " + e.getMessage());
        }
    }

    /**
     * 分页查询用户通知
     */
    @GetMapping("/user/{userId}")
    @Operation(summary = "获取用户通知", description = "分页查询用户通知列表")
    public Result<IPage<Notification>> getUserNotifications(
            @Parameter(description = "用户ID") @PathVariable("userId") Long userId,
            @Parameter(description = "页码") @RequestParam(name = "page", defaultValue = "1") Integer page,
            @Parameter(description = "每页大小") @RequestParam(name = "size", defaultValue = "10") Integer size,
            @Parameter(description = "通知类型") @RequestParam(required = false) String type,
            @Parameter(description = "通知状态") @RequestParam(required = false) String status,
            @Parameter(description = "优先级") @RequestParam(required = false) String priority,
            @Parameter(description = "是否已读") @RequestParam(required = false) Boolean isRead) {
        try {
            Page<Notification> pageParam = new Page<>(page, size);
            IPage<Notification> result = notificationService.getUserNotifications(pageParam, userId, type, status, priority, isRead);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取用户通知失败", e);
            return Result.error("获取用户通知失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户最近通知
     */
    @GetMapping("/user/{userId}/recent")
    @Operation(summary = "获取最近通知", description = "获取用户最近的通知")
    public Result<List<Notification>> getRecentNotifications(
            @Parameter(description = "用户ID") @PathVariable("userId") Long userId,
            @Parameter(description = "限制数量") @RequestParam(name = "limit", defaultValue = "10") Integer limit) {
        try {
            List<Notification> result = notificationService.getRecentNotifications(userId, limit);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取最近通知失败", e);
            return Result.error("获取最近通知失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户未读通知数量
     */
    @GetMapping("/user/{userId}/unread-count")
    @Operation(summary = "获取未读通知数量", description = "获取用户未读通知数量")
    public Result<Integer> getUnreadNotificationCount(@Parameter(description = "用户ID") @PathVariable("userId") Long userId) {
        try {
            Integer count = notificationService.getUnreadNotificationCount(userId);
            return Result.success(count);
        } catch (Exception e) {
            log.error("获取未读通知数量失败", e);
            return Result.error("获取未读通知数量失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户未读通知数量（按类型分组）
     */
    @GetMapping("/user/{userId}/unread-count-by-type")
    @Operation(summary = "按类型获取未读通知数量", description = "按类型分组获取用户未读通知数量")
    public Result<Map<String, Integer>> getUnreadNotificationCountByType(@Parameter(description = "用户ID") @PathVariable("userId") Long userId) {
        try {
            Map<String, Integer> result = notificationService.getUnreadNotificationCountByType(userId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("按类型获取未读通知数量失败", e);
            return Result.error("按类型获取未读通知数量失败: " + e.getMessage());
        }
    }

    /**
     * 获取高优先级未读通知
     */
    @GetMapping("/user/{userId}/high-priority-unread")
    @Operation(summary = "获取高优先级未读通知", description = "获取用户高优先级未读通知")
    public Result<List<Notification>> getHighPriorityUnreadNotifications(@Parameter(description = "用户ID") @PathVariable("userId") Long userId) {
        try {
            List<Notification> result = notificationService.getHighPriorityUnreadNotifications(userId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取高优先级未读通知失败", e);
            return Result.error("获取高优先级未读通知失败: " + e.getMessage());
        }
    }

    /**
     * 标记通知为已读
     */
    @PutMapping("/user/{userId}/{notificationId}/read")
    @Operation(summary = "标记为已读", description = "标记指定通知为已读")
    public Result<Boolean> markAsRead(
            @Parameter(description = "用户ID") @PathVariable("userId") Long userId,
            @Parameter(description = "通知ID") @PathVariable("notificationId") Long notificationId) {
        try {
            Boolean result = notificationService.markAsRead(userId, notificationId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("标记通知为已读失败", e);
            return Result.error("标记通知为已读失败: " + e.getMessage());
        }
    }

    /**
     * 批量标记通知为已读
     */
    @PutMapping("/user/{userId}/batch-read")
    @Operation(summary = "批量标记为已读", description = "批量标记通知为已读")
    public Result<Integer> batchMarkAsRead(
            @Parameter(description = "用户ID") @PathVariable("userId") Long userId,
            @Parameter(description = "通知ID列表") @RequestBody List<Long> notificationIds) {
        try {
            Integer count = notificationService.batchMarkAsRead(userId, notificationIds);
            return Result.success(count);
        } catch (Exception e) {
            log.error("批量标记通知为已读失败", e);
            return Result.error("批量标记通知为已读失败: " + e.getMessage());
        }
    }

    /**
     * 标记所有通知为已读
     */
    @PutMapping("/user/{userId}/mark-all-read")
    @Operation(summary = "标记所有为已读", description = "标记所有通知为已读")
    public Result<Integer> markAllAsRead(
            @Parameter(description = "用户ID") @PathVariable("userId") Long userId,
            @Parameter(description = "通知类型") @RequestParam(required = false) String type) {
        try {
            Integer count = notificationService.markAllAsRead(userId, type);
            return Result.success(count);
        } catch (Exception e) {
            log.error("标记所有通知为已读失败", e);
            return Result.error("标记所有通知为已读失败: " + e.getMessage());
        }
    }

    /**
     * 删除通知
     */
    @DeleteMapping("/user/{userId}/{notificationId}")
    @Operation(summary = "删除通知", description = "删除指定通知")
    public Result<Boolean> deleteNotification(
            @Parameter(description = "用户ID") @PathVariable("userId") Long userId,
            @Parameter(description = "通知ID") @PathVariable("notificationId") Long notificationId) {
        try {
            Boolean result = notificationService.deleteNotification(userId, notificationId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("删除通知失败", e);
            return Result.error("删除通知失败: " + e.getMessage());
        }
    }

    /**
     * 批量删除通知
     */
    @DeleteMapping("/user/{userId}/batch")
    @Operation(summary = "批量删除通知", description = "批量删除通知")
    public Result<Integer> batchDeleteNotifications(
            @Parameter(description = "用户ID") @PathVariable("userId") Long userId,
            @Parameter(description = "通知ID列表") @RequestBody List<Long> notificationIds) {
        try {
            Integer count = notificationService.batchDeleteNotifications(userId, notificationIds);
            return Result.success(count);
        } catch (Exception e) {
            log.error("批量删除通知失败", e);
            return Result.error("批量删除通知失败: " + e.getMessage());
        }
    }

    /**
     * 获取通知详情
     */
    @GetMapping("/user/{userId}/{notificationId}")
    @Operation(summary = "获取通知详情", description = "获取指定通知的详细信息")
    public Result<Notification> getNotificationDetail(
            @Parameter(description = "用户ID") @PathVariable("userId") Long userId,
            @Parameter(description = "通知ID") @PathVariable("notificationId") Long notificationId) {
        try {
            Notification result = notificationService.getNotificationDetail(userId, notificationId);
            if (result != null) {
                return Result.success(result);
            } else {
                return Result.error("通知不存在或无权限访问");
            }
        } catch (Exception e) {
            log.error("获取通知详情失败", e);
            return Result.error("获取通知详情失败: " + e.getMessage());
        }
    }

    /**
     * 获取通知统计信息
     */
    @GetMapping("/statistics")
    @Operation(summary = "获取通知统计", description = "获取通知统计信息")
    public Result<Map<String, Object>> getNotificationStatistics(
            @Parameter(description = "用户ID") @RequestParam(required = false) Long userId,
            @Parameter(description = "开始时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        try {
            Map<String, Object> result = notificationService.getNotificationStatistics(userId, startTime, endTime);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取通知统计信息失败", e);
            return Result.error("获取通知统计信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户通知偏好
     */
    @GetMapping("/user/{userId}/preferences")
    @Operation(summary = "获取通知偏好", description = "获取用户通知偏好统计")
    public Result<List<Map<String, Object>>> getUserNotificationPreferences(@Parameter(description = "用户ID") @PathVariable Long userId) {
        try {
            List<Map<String, Object>> result = notificationService.getUserNotificationPreferences(userId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取用户通知偏好失败", e);
            return Result.error("获取用户通知偏好失败: " + e.getMessage());
        }
    }

    /**
     * 创建定时提醒
     */
    @PostMapping("/scheduled-reminder")
    @Operation(summary = "创建定时提醒", description = "创建定时提醒通知")
    public Result<Notification> createScheduledReminder(
            @Parameter(description = "用户ID") @RequestParam Long userId,
            @Parameter(description = "标题") @RequestParam String title,
            @Parameter(description = "内容") @RequestParam String content,
            @Parameter(description = "计划发送时间") @RequestParam 
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime scheduledAt,
            @Parameter(description = "重复类型") @RequestParam(name = "repeatType", defaultValue = "ONCE") String repeatType) {
        try {
            Notification result = notificationService.createScheduledReminder(userId, title, content, scheduledAt, repeatType);
            return Result.success(result);
        } catch (Exception e) {
            log.error("创建定时提醒失败", e);
            return Result.error("创建定时提醒失败: " + e.getMessage());
        }
    }

    /**
     * 取消定时提醒
     */
    @DeleteMapping("/user/{userId}/scheduled-reminder/{notificationId}")
    @Operation(summary = "取消定时提醒", description = "取消定时提醒通知")
    public Result<Boolean> cancelScheduledReminder(
            @Parameter(description = "用户ID") @PathVariable Long userId,
            @Parameter(description = "通知ID") @PathVariable Long notificationId) {
        try {
            Boolean result = notificationService.cancelScheduledReminder(userId, notificationId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("取消定时提醒失败", e);
            return Result.error("取消定时提醒失败: " + e.getMessage());
        }
    }

    /**
     * 更新通知设置
     */
    @PutMapping("/user/{userId}/settings")
    @Operation(summary = "更新通知设置", description = "更新用户通知设置")
    public Result<Boolean> updateNotificationSettings(
            @Parameter(description = "用户ID") @PathVariable Long userId,
            @Parameter(description = "通知设置") @RequestBody Map<String, Object> settings) {
        try {
            Boolean result = notificationService.updateNotificationSettings(userId, settings);
            return Result.success(result);
        } catch (Exception e) {
            log.error("更新通知设置失败", e);
            return Result.error("更新通知设置失败: " + e.getMessage());
        }
    }

    /**
     * 获取通知设置
     */
    @GetMapping("/user/{userId}/settings")
    @Operation(summary = "获取通知设置", description = "获取用户通知设置")
    public Result<Map<String, Object>> getNotificationSettings(@Parameter(description = "用户ID") @PathVariable Long userId) {
        try {
            Map<String, Object> result = notificationService.getNotificationSettings(userId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取通知设置失败", e);
            return Result.error("获取通知设置失败: " + e.getMessage());
        }
    }

    /**
     * 创建紧急通知
     */
    @PostMapping("/emergency")
    @Operation(summary = "创建紧急通知", description = "创建紧急通知")
    public Result<Notification> createEmergencyNotification(
            @Parameter(description = "用户ID") @RequestParam Long userId,
            @Parameter(description = "标题") @RequestParam String title,
            @Parameter(description = "内容") @RequestParam String content,
            @Parameter(description = "操作链接") @RequestParam(required = false) String actionUrl) {
        try {
            Notification result = notificationService.createEmergencyNotification(userId, title, content, actionUrl);
            return Result.success(result);
        } catch (Exception e) {
            log.error("创建紧急通知失败", e);
            return Result.error("创建紧急通知失败: " + e.getMessage());
        }
    }

    /**
     * 广播系统通知
     */
    @PostMapping("/broadcast")
    @Operation(summary = "广播系统通知", description = "广播系统通知给指定用户")
    public Result<Integer> broadcastSystemNotification(
            @Parameter(description = "标题") @RequestParam String title,
            @Parameter(description = "内容") @RequestParam String content,
            @Parameter(description = "目标用户ID列表") @RequestBody(required = false) List<Long> targetUserIds) {
        try {
            Integer count = notificationService.broadcastSystemNotification(title, content, targetUserIds);
            return Result.success(count);
        } catch (Exception e) {
            log.error("广播系统通知失败", e);
            return Result.error("广播系统通知失败: " + e.getMessage());
        }
    }

    /**
     * 处理待发送通知
     */
    @PostMapping("/process-pending")
    @Operation(summary = "处理待发送通知", description = "处理待发送的通知")
    public Result<Integer> processPendingNotifications(
            @Parameter(description = "限制数量") @RequestParam(name = "limit", defaultValue = "100") Integer limit) {
        try {
            Integer count = notificationService.processPendingNotifications(limit);
            return Result.success(count);
        } catch (Exception e) {
            log.error("处理待发送通知失败", e);
            return Result.error("处理待发送通知失败: " + e.getMessage());
        }
    }

    /**
     * 重试失败通知
     */
    @PostMapping("/retry-failed")
    @Operation(summary = "重试失败通知", description = "重试发送失败的通知")
    public Result<Integer> retryFailedNotifications(
            @Parameter(description = "限制数量") @RequestParam(name = "limit", defaultValue = "50") Integer limit) {
        try {
            Integer count = notificationService.retryFailedNotifications(limit);
            return Result.success(count);
        } catch (Exception e) {
            log.error("重试失败通知异常", e);
            return Result.error("重试失败通知异常: " + e.getMessage());
        }
    }

    /**
     * 清理过期通知
     */
    @DeleteMapping("/cleanup-expired")
    @Operation(summary = "清理过期通知", description = "清理过期的通知")
    public Result<Integer> cleanupExpiredNotifications() {
        try {
            Integer count = notificationService.cleanupExpiredNotifications();
            return Result.success(count);
        } catch (Exception e) {
            log.error("清理过期通知失败", e);
            return Result.error("清理过期通知失败: " + e.getMessage());
        }
    }
}